package org.smartboot.jdk;

import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public abstract class AsynchronousSocketChannel implements AsynchronousByteChannel, NetworkChannel {


    protected AsynchronousSocketChannel() {
    }

    public static AsynchronousSocketChannel open(AsynchronousChannelGroup group)
            throws IOException {
        AsynchronousChannelProvider provider = (group == null) ?
                AsynchronousChannelProvider.provider() : group.provider();
        return provider.openAsynchronousSocketChannel(group);
    }


    @Override
    public abstract AsynchronousSocketChannel bind(SocketAddress local)
            throws IOException;


    public abstract AsynchronousSocketChannel shutdownInput() throws IOException;


    public abstract AsynchronousSocketChannel shutdownOutput() throws IOException;


    public abstract SocketAddress getRemoteAddress() throws IOException;


    public abstract <A> void connect(SocketAddress remote,
                                     A attachment,
                                     CompletionHandler<Void, ? super A> handler);


    public abstract Future<Void> connect(SocketAddress remote);


    public abstract <A> void read(ByteBuffer dst,
                                  long timeout,
                                  TimeUnit unit,
                                  A attachment,
                                  CompletionHandler<Integer, ? super A> handler);


    @Override
    public final <A> void read(ByteBuffer dst,
                               A attachment,
                               CompletionHandler<Integer, ? super A> handler) {
        read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
    }


    @Override
    public abstract Future<Integer> read(ByteBuffer dst);


    public abstract <A> void write(ByteBuffer src,
                                   long timeout,
                                   TimeUnit unit,
                                   A attachment,
                                   CompletionHandler<Integer, ? super A> handler);


    @Override
    public final <A> void write(ByteBuffer src,
                                A attachment,
                                CompletionHandler<Integer, ? super A> handler) {
        write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler);
    }


    @Override
    public abstract Future<Integer> write(ByteBuffer src);


    public abstract <A> void write(ByteBuffer[] srcs,
                                   int offset,
                                   int length,
                                   long timeout,
                                   TimeUnit unit,
                                   A attachment,
                                   CompletionHandler<Long, ? super A> handler);


    @Override
    public abstract SocketAddress getLocalAddress() throws IOException;
}
